Most of today's software is written in “unsafe” languages, such as C or C++, which is compiled into native machine code using compilers targeted to specific processor instruction set architectures. These languages are unsafe because they have provisions for direct un-checked memory manipulation or access, either via built-in functionality (i.e., pointer indirection and manipulation), extensions, or in-line assembly. For example, a memory operation for a particular unsafe application module may actually change the memory in a portion of the memory address space that is assigned to another application module. This may lead to corruption of documents produced by the other application or a system crash, among other undesired effects. Thus, the native code the languages generate is not trustworthy.
The code safety problem is exacerbated by today's modular code environments. Operating systems and software programs are getting more modular as they seek to provide richer features. They are increasingly built out of components developed independently, often by different teams. This leads to packages built out of components that have different levels of trustworthiness. For example, while the kernel of an operating system (OS) may contain trusted code, it interfaces with device drivers written by third-party vendors. In general, the OS vendor cannot verify the trustworthiness of the third party code. This causes a delineation of trust boundaries in the operating system. Furthermore, applications running on the operating system may also have such a delineation of trust boundary.
More specifically, many large applications use dynamically linked libraries (DLLs), often developed by independent software vendors. For example, a browser often uses a range of plug-ins developed by completely independent vendors. The large number of third-party modules used in many of today's program environments often make it impractical or even impossible to determine whether the environment is entirely safe.
One technique for addressing the code safety problem is to use a type-safe language. For example, Java and C# are type-safe languages, which do not allow direct memory manipulation. Rather, these languages run on a platform-dependent virtual machine (e.g., the Java Virtual Machine or JVM), which manages all memory interfaces with the processor and/or operating system. The virtual machine provides a level of abstraction between the platform-independent programming language and the platform specific processor instruction set architecture. In fact, platform-independent languages such as JAVA do not support direct memory manipulation or access.
Although Java and C# do not allow direct memory manipulation, they are often required to interface with code or modules that do. For example, it is often necessary to access low-level system functionality (for example, to output data to a monitor) that is not supported by a platform-independent language. Thus, both Java and C# provide extensions to support calls to modules or code written in unsafe languages. Accordingly, such “mixed” program code can no longer be considered inherently safe. This compromises the trustworthiness of the program code.